package com.bawei.module_publish.openlive.ui

import android.Manifest
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.bawei.lib_common.base.BaseApplication
import com.bawei.lib_common.base.utils.LoggerUtils
import com.bawei.lib_common.entity.WebSocketEntity
import com.bawei.lib_common.websocket.WebSocketManager
import com.bawei.lib_mvi.Router
import com.bawei.lib_mvi.base.BaseMVIActivity
import com.bawei.lib_storage.mmkv.AuthMMKV
import com.bawei.lib_storage.mmkv.AuthMMKV.username
import com.bawei.lib_storage.mmkv.UserMMKV
import com.bawei.module_publish.R
import com.bawei.module_publish.databinding.ActivityLiveStartBinding
import com.bawei.module_publish.openlive.adapter.ChatAdapter
import com.bawei.module_publish.openlive.event.ExplainSuccessEvent
import com.bawei.module_publish.openlive.intent.LiveIntent
import com.bawei.module_publish.openlive.model.entity.OpenLiveBody
import com.bawei.module_publish.openlive.state.LiveState
import com.bawei.module_publish.openlive.viewmodel.LiveViewModel
import com.blankj.utilcode.util.ToastUtils
import com.bumptech.glide.Glide
import com.google.gson.Gson
import com.hyphenate.EMCallBack
import com.hyphenate.EMMessageListener
import com.hyphenate.EMValueCallBack
import com.hyphenate.chat.EMChatRoom
import com.hyphenate.chat.EMClient
import com.hyphenate.chat.EMMessage
import com.hyphenate.exceptions.HyphenateException
import com.opensource.svgaplayer.SVGACallback
import com.opensource.svgaplayer.SVGAParser
import com.opensource.svgaplayer.SVGAVideoEntity
import com.tencent.rtmp.ITXLivePushListener
import com.tencent.rtmp.TXLiveBase
import com.tencent.rtmp.TXLiveConstants
import com.tencent.rtmp.TXLivePushConfig
import com.tencent.rtmp.TXLivePusher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONObject
import java.net.URL


private const val TAG = "LiveStartActivity"

@Route(path = Router.Ui.LIVE_ACTIVITY)
class LiveStartActivity : BaseMVIActivity() {
    private val binding: ActivityLiveStartBinding by lazy {
        ActivityLiveStartBinding.inflate(layoutInflater)
    }
    private lateinit var liveViewModel: LiveViewModel

    private var mLivePusher: TXLivePusher? = null
    private var mLivePushConfig: TXLivePushConfig? = null

    private val giftBubbleMap = mutableMapOf<Int, Pair<View, Int>>() // key: giftId, value: (bubbleView, count)
    private val bigGiftIds = setOf(1, 3, 6) // 跑车、王冠、玫瑰的id

    // 权限请求
    private val permissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        val granted = permissions.all { it.value }
        if (granted) {
            startLive()
        } else {
            Toast.makeText(this, "请授予所有直播所需权限", Toast.LENGTH_SHORT).show()
            finish()
        }
    }

    private var roomId: String = "285417033236483"

    private lateinit var chatAdapter: ChatAdapter

    private val chatRoomId = "285417033236483" // 全局唯一聊天室ID
    private var isMessageListenerRegistered = false // 添加标记，避免重复注册

    private val messageListener = object : EMMessageListener {
        override fun onMessageReceived(messages: List<EMMessage>?) {
            Log.d("环信调试", "onMessageReceived: 收到消息, size=${messages?.size}")
            messages?.forEach { msg ->
                Log.d(
                    "环信调试",
                    "onMessageReceived: 消息内容: ${msg.body}, from: ${msg.from}, to: ${msg.to}, attributes: ${msg.attributes}"
                )

                // 只处理当前聊天室的消息
                if (msg.chatType == EMMessage.ChatType.ChatRoom && msg.to == chatRoomId) {
                    runOnUiThread {
                        chatAdapter.addMessage(msg)
                        binding.openLiveRec.scrollToPosition(chatAdapter.itemCount - 1)
                    }
                }
            }
        }

        // 其他方法可留空
        override fun onCmdMessageReceived(messages: List<EMMessage>?) {}
        override fun onMessageRead(messages: List<EMMessage>?) {}
        override fun onMessageDelivered(messages: List<EMMessage>?) {}
        override fun onMessageRecalled(messages: List<EMMessage>?) {}
        override fun onMessageChanged(message: EMMessage?, change: Any?) {}
    }
    private val webSocket = WebSocketManager(
        onMessage = {
            val data= Gson().fromJson(it, WebSocketEntity::class.java)
            when(data.type){
                8->{
                    val fileName = "http://10.161.9.80:7015/gift/download/"+parsePart(data.data,"gift","svgaPath")!!.substringBefore(".")
                    Log.d("SVGA", "url：$fileName")
                    Log.d("SVGA", "url2：${data.data}")
                    playGift(fileName)
                    val jsonObject = JSONObject(data.data)
                    val giftJson = jsonObject.getJSONObject("gift")
                    val imgUrl = giftJson.optString("imgUrl")
                    val title = giftJson.optString("title")
                    val id = giftJson.optInt("id")
                    val price = giftJson.optInt("price")
                    val svgaPath = giftJson.optString("svgaPath")
                    val username = jsonObject.optString("username")
                    LoggerUtils.d("SVGA", "imgUrl: $imgUrl, title: $title, id: $id, price: $price, svgaPath: $svgaPath, username: $username")
                    // 你可以在这里调用 showGiftBubble 或其它逻辑
                }

                else -> {}
            }
        }
    )
    fun Int.dp2px(context: Context): Int =
        (this * context.resources.displayMetrics.density + 0.5f).toInt()
    fun parsePart(jsonString: String,name:String,part:String): String? {
        return try {
            val jsonObject = JSONObject(jsonString)
            val giftObject = jsonObject.getJSONObject(name)
            giftObject.getString(part)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }
    fun playGift(fileName:String){
        val parser = SVGAParser(this)
        parser.decodeFromURL(URL(fileName),object : SVGAParser.ParseCompletion {
            override fun onComplete(videoItem: SVGAVideoEntity) {
                binding.giftSvga.visibility = View.VISIBLE
                binding.giftSvga.setVideoItem(videoItem)
                binding.giftSvga.loops=1
                binding.giftSvga.startAnimation()
                binding.giftSvga.callback = object : SVGACallback {
                    override fun onFinished() {
                        binding.giftSvga.clearAnimation()
                        binding.giftSvga.setVideoItem(null)
                        binding.giftSvga.visibility = View.GONE
                    }
                    override fun onPause() {}
                    override fun onRepeat() {}
                    override fun onStep(frame: Int, percentage: Double) {}
                }
            }

            override fun onError() {
                Log.d("SVGA", "onError: "+"失败")
            }

        })
    }


    override fun initView() {
        super.initView()
        liveViewModel = ViewModelProvider(this)[LiveViewModel::class.java]
        TXLiveBase.setLogLevel(TXLiveConstants.LOG_LEVEL_VERBOSE) // 开启详细日志
        // 请求权限
        permissionLauncher.launch(
            arrayOf(
                Manifest.permission.CAMERA,
                Manifest.permission.RECORD_AUDIO,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            )
        )
        webSocket.connect("ws://10.161.9.80:7015/liveRoom/websocket/${roomId}/${AuthMMKV.uId}")
        initAdapter()
        // 初始化环信连接
        initHyphenateConnection()
        sendMessage("欢迎来到直播间！")
        Glide.with( this).load("https://picsum.photos/200/300").circleCrop().into(binding.liveDetailAuthorIcon)
    }

    override fun initData() {
        super.initData()
        val openLiveBody = OpenLiveBody("日赚十万块", "285417033236483", "jjj")
        lifecycleScope.launch {
            liveViewModel.intents.send(LiveIntent.OpenLive(openLiveBody))
        }
        lifecycleScope.launch {
            while (isActive) {
                // 确保在生命周期至少为 STARTED 时执行请求
                repeatOnLifecycle(Lifecycle.State.STARTED) {
                    liveViewModel.intents.send(LiveIntent.GetOnlineNum(roomId))
                }
                // 延迟5秒后执行下一次循环（注意：延迟期间生命周期变化会被感知）
                delay(5000)
            }
        }
        binding.layoutHb.setOnClickListener {
            FansRedPacketDialog(roomId).show(supportFragmentManager, "FansRedPacketDialog")
        }
        binding.layoutShopp.setOnClickListener {
            LiveGoodsDialog(roomId).show(supportFragmentManager, "LiveGoodsDialog")
        }
        binding.back.setOnClickListener {
            lifecycleScope.launch {
                liveViewModel.intents.send(LiveIntent.DeleteLiveRoom(roomId))
            }
            finish()
        }
        binding.layoutMore.setOnClickListener {
            LiveAdDialog().apply {
                setOnAdSentListener { ad ->
                    // 这里可以处理广告发送逻辑，比如发送到聊天室
                    sendMessage("【广告】${ad.desc}")
//                    Toast.makeText(this@LiveStartActivity, "广告已发送", Toast.LENGTH_SHORT).show()
                }
            }.show(supportFragmentManager, "LiveAdDialog")
        }
    }

    override fun generateViewModel() {

    }

    override fun getLayoutRootView(): View {
        return binding.root
    }

    override fun handleState() {

    }

    override fun onStart() {
        super.onStart()
        EventBus.getDefault().register(this)
    }

    override fun onStop() {
        super.onStop()
        EventBus.getDefault().unregister(this)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onExplainSuccess(event: ExplainSuccessEvent) {
        LoggerUtils.d("时间总线", "onExplainSuccess: 获取商品成功, 商品ID: ${event.goodsList}")
        binding.flagGoodsContainer.visibility = View.VISIBLE
        val liveImg = binding.flagGoodsContainer.findViewById<ImageView>(R.id.ivGoodsImg)
        val tvTitle = binding.flagGoodsContainer.findViewById<TextView>(R.id.tvGoodsTitle)
        val livePrice = binding.flagGoodsContainer.findViewById<TextView>(R.id.tvPrice)
        val close = binding.flagGoodsContainer.findViewById<ImageView>(R.id.flag_close)
        val btnCancel = binding.flagGoodsContainer.findViewById<TextView>(R.id.btnCancel)
        Glide.with(this).load(event.goodsList.mainImgUrl).into(liveImg)
        tvTitle.text = "${event.goodsList.title}"
        livePrice.text = "¥${event.goodsList.marketPriceFee}"
        close.setOnClickListener {
            binding.flagGoodsContainer.visibility = View.GONE
        }
        btnCancel.setOnClickListener {
            binding.flagGoodsContainer.visibility = View.GONE
        }
    }

    // 初始化环信连接
    private fun initHyphenateConnection() {
        Log.d("环信调试", "initHyphenateConnection: 开始初始化环信连接, 当前账号: $username")
        if (!EMClient.getInstance().isLoggedInBefore) {
            Log.d("环信调试", "initHyphenateConnection: 环信未登录，开始登录 username=$username")
            EMClient.getInstance().login(username, AuthMMKV.password, object : EMCallBack {
                override fun onSuccess() {
                    Log.d("环信调试", "环信登录成功 username=$username")
                    runOnUiThread {
                        joinChatRoom()
                        Toast.makeText(this@LiveStartActivity, "环信登录成功", Toast.LENGTH_SHORT)
                            .show()
                    }
                }

                override fun onError(code: Int, error: String?) {
                    Log.e("环信调试", "环信登录失败: code=$code, error=$error, username=$username")
                    runOnUiThread {
                        ToastUtils.showLong( "环信登录失败: $error")
                    }
                }

                override fun onProgress(progress: Int, status: String?) {
                    Log.d("环信调试", "环信登录进度: $progress, $status, username=$username")
                }
            })
        } else {
            Log.d("环信调试", "环信已登录，直接加入聊天室 username=$username")
            joinChatRoom()
        }
    }

    // 加入聊天室
    private fun joinChatRoom() {
        Log.d("环信调试", "joinChatRoom: 开始加入聊天室 chatRoomId=$chatRoomId")
        lifecycleScope.launch(Dispatchers.IO) {
            try {
                EMClient.getInstance().chatroomManager()
                    .joinChatRoom(chatRoomId, object : EMValueCallBack<EMChatRoom> {
                        override fun onSuccess(value: EMChatRoom?) {
                            Log.d(
                                "环信调试",
                                "joinChatRoom: 加入聊天室成功 chatRoomId=$chatRoomId, 当前账号: ${EMClient.getInstance().currentUser}"
                            )
                            runOnUiThread {
                                // 注册消息监听器
                                if (!isMessageListenerRegistered) {
                                    EMClient.getInstance().chatManager()
                                        .addMessageListener(messageListener)
                                    isMessageListenerRegistered = true
                                    Log.d("环信调试", "addMessageListener: 注册成功")
                                }
                                Toast.makeText(
                                    this@LiveStartActivity,
                                    "已创建聊天室",
                                    Toast.LENGTH_SHORT
                                ).show()
                            }
                        }

                        override fun onError(error: Int, errorMsg: String?) {
                            Log.e(
                                "环信调试",
                                "joinChatRoom: 加入聊天室失败 chatRoomId=$chatRoomId, error=$error, errorMsg=$errorMsg"
                            )
                            runOnUiThread {
                                Toast.makeText(
                                    this@LiveStartActivity,
                                    "加入聊天室失败: $errorMsg",
                                    Toast.LENGTH_SHORT
                                ).show()
                            }
                        }
                    })
            } catch (e: HyphenateException) {
                Log.e(
                    "环信调试",
                    "joinChatRoom: 加入聊天室异常 chatRoomId=$chatRoomId, exception=${e.message}"
                )
                runOnUiThread {
                    Toast.makeText(
                        this@LiveStartActivity,
                        "创建聊天室异常: ${e.message}",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        }
    }

    // 退出聊天室
    private fun leaveChatRoom() {
        Log.d("环信调试", "leaveChatRoom: 开始退出聊天室 chatRoomId=$chatRoomId")
        lifecycleScope.launch(Dispatchers.IO) {
            try {
                EMClient.getInstance().chatroomManager().leaveChatRoom(chatRoomId)
                Log.d("环信调试", "leaveChatRoom: 退出聊天室成功 chatRoomId=$chatRoomId")
            } catch (e: HyphenateException) {
                Log.e(
                    "环信调试",
                    "leaveChatRoom: 退出聊天室异常 chatRoomId=$chatRoomId, exception=${e.message}"
                )
            }
        }
    }

    // 释放环信资源
    private fun releaseHyphenateResources() {
        Log.d("环信调试", "releaseHyphenateResources: 开始释放环信资源")

        // 1. 移除消息监听器
        if (isMessageListenerRegistered) {
            EMClient.getInstance().chatManager().removeMessageListener(messageListener)
            isMessageListenerRegistered = false
            Log.d("环信调试", "removeMessageListener: 已移除监听器")
        }

        // 2. 退出聊天室
        leaveChatRoom()

        // 3. 退出环信登录
        if (EMClient.getInstance().isLoggedInBefore) {
            EMClient.getInstance().logout(true, object : EMCallBack {
                override fun onSuccess() {
                    Log.d("环信调试", "环信退出登录成功")
                }

                override fun onError(code: Int, message: String) {
                    Log.e("环信调试", "环信退出登录失败: code=$code, message=$message")
                }
            })
        }
    }

    // 发送消息到聊天室
    private fun sendMessage(content: String) {
        if (content.isBlank()) {
            Toast.makeText(this, "消息内容不能为空", Toast.LENGTH_SHORT).show()
            return
        }

        lifecycleScope.launch(Dispatchers.IO) {
            try {
                // 创建文本消息
                val message = EMMessage.createTxtSendMessage(content, chatRoomId)
                message.chatType = EMMessage.ChatType.ChatRoom

                // 设置消息属性（可选）
                message.setAttribute("nickname", username)
                message.setAttribute("isHost", true)

                // 发送消息
                EMClient.getInstance().chatManager().sendMessage(message)

                Log.d("环信调试", "sendMessage: 发送消息成功 content=$content")
                runOnUiThread {
//                    Toast.makeText(this@LiveStartActivity, "消息发送成功", Toast.LENGTH_SHORT)
//                        .show()
                }
            } catch (e: Exception) {
                Log.e(
                    "环信调试",
                    "sendMessage: 发送消息失败 content=$content, exception=${e.message}"
                )
                runOnUiThread {
                    Toast.makeText(
                        this@LiveStartActivity,
                        "消息发送失败: ${e.message}",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        }
    }

    private fun startLive() {
        mLivePushConfig = TXLivePushConfig().apply {
            // 可根据需求设置分辨率、码率等
            setVideoResolution(TXLiveConstants.VIDEO_RESOLUTION_TYPE_640_480)
            setVideoBitrate(1500)
            setMinVideoBitrate(800)
            setMaxVideoBitrate(1800)
            setVideoFPS(20)
            setHardwareAcceleration(TXLiveConstants.ENCODE_VIDEO_HARDWARE)
        }
        mLivePusher = TXLivePusher(this).apply {
            setConfig(mLivePushConfig)
            // 设置推流监听器
            setPushListener(object : ITXLivePushListener {
                override fun onPushEvent(event: Int, bundle: Bundle?) {
                    when (event) {
                        // 推流开始（SDK 已启动推流线程）
                        TXLiveConstants.PUSH_EVT_PUSH_BEGIN -> {
                            runOnUiThread {
                                Toast.makeText(
                                    this@LiveStartActivity,
                                    "推流已启动，正在连接服务器...",
                                    Toast.LENGTH_SHORT
                                ).show()
                                // 可选：更新 UI（如隐藏"开始"按钮，显示"连接中"）
                            }
                        }
                        // 网络断开（推流失败）
                        TXLiveConstants.PUSH_ERR_NET_DISCONNECT -> {
                            runOnUiThread {
                                Toast.makeText(
                                    this@LiveStartActivity,
                                    "网络断开，推流已停止",
                                    Toast.LENGTH_SHORT
                                ).show()
                                // 可选：尝试重连或提示用户检查网络
                            }
                            LoggerUtils.d(TAG, "推流失败：网络断开，事件码：$event")
                        }
                        // 相机打开失败（推流失败）
                        TXLiveConstants.PUSH_ERR_OPEN_CAMERA_FAIL -> {
                            runOnUiThread {
                                Toast.makeText(
                                    this@LiveStartActivity,
                                    "无法打开相机，请检查权限或设备",
                                    Toast.LENGTH_SHORT
                                ).show()
                                finish() // 无法恢复则退出
                            }
                            LoggerUtils.d(TAG, "推流失败：相机打开失败，事件码：$event")
                        }
                        // 麦克风打开失败（推流失败）
                        TXLiveConstants.PUSH_ERR_OPEN_MIC_FAIL -> {
                            runOnUiThread {
                                Toast.makeText(
                                    this@LiveStartActivity,
                                    "无法打开麦克风，请检查权限或设备",
                                    Toast.LENGTH_SHORT
                                ).show()
                                finish() // 无法恢复则退出
                            }
                            LoggerUtils.d(TAG, "推流失败：麦克风打开失败，事件码：$event")
                        }
                    }
                }

                override fun onNetStatus(bundle: Bundle?) {

                }
            })
            // 启动本地摄像头预览
            startCameraPreview(binding.playerView)
            lifecycleScope.launch {
                repeatOnLifecycle(Lifecycle.State.STARTED) {
                    liveViewModel._liveOpenFlow.collect {
                        when (it) {
                            is LiveState.Init -> {
                                LoggerUtils.d(TAG, "初始化成功")
                            }

                            is LiveState.Empty -> {
                                LoggerUtils.d(TAG, "数据为空")
                            }

                            is LiveState.Failed -> {
                                LoggerUtils.d(TAG, "请求失败")
                            }

                            is LiveState.OpenLiveSuccess -> {
                                Log.d(TAG, "handleState: ${it.msg}")
                                // 启动推流
                                //"rtmp://10.161.9.80:8066/live/14796812519"
                                val rtmpURL =
                                    "rtmp://207376.push.tlivecloud.com/live/live?txSecret=309d6b02c2740ef6ed7135db4c88e321&txTime=68686FB4"
                                val ret = startPusher(it.msg.push_url)
                                if (ret == -5) {
                                    Log.i("TX", "startRTMPPush: license 校验失败")
                                    Toast.makeText(
                                        this@LiveStartActivity,
                                        "license 校验失败",
                                        Toast.LENGTH_SHORT
                                    ).show()
                                }
                                roomId = it.msg.room_id
                            }

                            else -> {
                                LoggerUtils.d(TAG, "其他状态")
                            }
                        }
                    }
                }
            }
            lifecycleScope.launch {
                repeatOnLifecycle(Lifecycle.State.STARTED) {
                    liveViewModel._deleteLiveNumFlow.collect {
                        when (it) {
                            is LiveState.Init -> {
                                LoggerUtils.d(TAG, "初始化成功")
                            }

                            is LiveState.Empty -> {
                                LoggerUtils.d(TAG, "数据为空")
                            }

                            is LiveState.Failed -> {
                                LoggerUtils.d(TAG, "请求失败")
                            }

                            is LiveState.DeleteLiveRoomSuccess -> {
                                Log.d(TAG, "handleState: ${it.msg}")
                                //环信退出登录
                                EMClient.getInstance().logout(true, object : EMCallBack {
                                    override fun onSuccess() {
                                        LoggerUtils.d("环信调试", "环信退出登录成功")
                                    }

                                    override fun onError(code: Int, message: String) {
                                        LoggerUtils.d("环信调试", "环信退出登录失败")
                                    }
                                })
                            }

                            else -> {
                                LoggerUtils.d(TAG, "其他状态")
                            }
                        }
                    }
                }
            }
            lifecycleScope.launch {
                repeatOnLifecycle(Lifecycle.State.STARTED) {
                    liveViewModel._onlineNumFlow.collect {
                        when (it) {
                            is LiveState.Init -> {
                                LoggerUtils.d(TAG, "初始化成功")
                            }

                            is LiveState.Empty -> {
                                LoggerUtils.d(TAG, "数据为空")
                            }

                            is LiveState.Failed -> {
                                LoggerUtils.d(TAG, "请求失败")
                            }

                            is LiveState.GetOnlineNumSuccess -> {
                                Log.d(TAG, "handleState: ${it.msg}")
                                binding.audienceNum.text = "${it.msg.size}"
                            }

                            else -> {
                                LoggerUtils.d(TAG, "其他状态")
                            }
                        }
                    }
                }
            }
        }
    }

    private fun initAdapter() {
        chatAdapter = ChatAdapter()
        binding.openLiveRec.adapter = chatAdapter
        binding.openLiveRec.layoutManager = LinearLayoutManager(this)
    }

    private fun stopLive() {
        mLivePusher?.stopPusher()
        mLivePusher?.stopCameraPreview(true)
    }

    override fun onDestroy() {
        super.onDestroy()
        // 1. 停止直播推流
        stopLive()

        // 2. 释放环信资源
        releaseHyphenateResources()

        // 3. 删除直播间
        lifecycleScope.launch {
            liveViewModel.intents.send(LiveIntent.DeleteLiveRoom(roomId))
        }
        webSocket.disconnect()
    }
}